# -*- codeing = utf-8 -*-
# @Time: 2022/1/9 21:07
# @Author: Foxhuty
# @File: exam_room_arrange.py
# @Software: PyCharm
# @Based on python 3.9
import pandas as pd
import time
import os
import warnings

warnings.simplefilter('ignore',FutureWarning)


class ExamRoom(object):
    """
    用于计算生成考室安排信息，含每考室考生名单 ，分班考室名单，考生座签。
    要求文件必须有以下字段：序号，姓名，班级，考号，总分。否则不能生成，程序报错！
    """

    numbers_in_room = None

    def __init__(self, path):
        self.path = path

    def __str__(self):
        return f'正在按{os.path.basename(self.path)}编制考室。'

    def exam_room_info(self):
        """
        计算生成文理科各考室学生名单
        :return:
        """
        df_arts = pd.read_excel(self.path, sheet_name='文科', index_col='序号',
                                dtype={'班级': str, '考号': str, '序号': str})
        df_science = pd.read_excel(self.path, sheet_name='理科', index_col='序号',
                                   dtype={'班级': str, '考号': str, '序号': str})
        df_arts.sort_values(by='总分', ascending=False, inplace=True)
        df_science.sort_values(by='总分', ascending=False, inplace=True)
        if len(df_arts) % ExamRoom.numbers_in_room != 0:
            room_numbers = [f'文科第{str(i + 1)}考室' for i in
                            list(range(len(df_arts) // ExamRoom.numbers_in_room + 1))]
        else:
            room_numbers = [f'文科第{str(i + 1)}考室' for i in list(range(len(df_arts) // ExamRoom.numbers_in_room))]
        if len(df_science) % ExamRoom.numbers_in_room != 0:
            room_numbers_science = [f'理科第{str(i + 1)}考室' for i in
                                    list(range(len(df_science) // ExamRoom.numbers_in_room + 1))]
        else:
            room_numbers_science = [f'理科第{str(i + 1)}考室' for i in
                                    list(range(len(df_science) // ExamRoom.numbers_in_room))]
        print(room_numbers)
        print(room_numbers_science)
        df_arts = df_arts.copy()
        df_science = df_science.copy()
        df_arts['考室号'] = None
        df_arts['座位号'] = None
        df_arts = df_arts.loc[:, ['班级', '姓名', '考号', '考室号', '座位号']]
        df_arts.reset_index(drop=True, inplace=True)

        df_science['考室号'] = None
        df_science['座位号'] = None
        df_science = df_science.loc[:, ['班级', '姓名', '考号', '考室号', '座位号']]
        df_science.reset_index(drop=True, inplace=True)

        df_room_students = []
        df_room_students_science = []
        arts = pd.DataFrame(columns=df_arts.columns)
        science = pd.DataFrame(columns=df_science.columns)
        for idx, room_number in enumerate(room_numbers):
            begin = idx * ExamRoom.numbers_in_room
            end = begin + ExamRoom.numbers_in_room
            df_room_student = df_arts.iloc[begin:end]
            df_room_students.append((idx, room_number, df_room_student))
            # print(df_room_students)
        writer = pd.ExcelWriter(r'D:\成绩统计结果\文理科考室安排表.xlsx')
        for idx, room_number, df_room_student in df_room_students:
            for i in df_room_student.index:
                df_room_student = df_room_student.copy()
                df_room_student['考室号'].at[i] = room_number
                df_room_student['座位号'].at[
                    i] = i + 1 if i < ExamRoom.numbers_in_room else i - idx * ExamRoom.numbers_in_room + 1
            df_room_student.to_excel(writer, sheet_name=room_number, index=False)
            arts = arts.append(df_room_student)
        for idx, room_number in enumerate(room_numbers_science):
            begin = idx * ExamRoom.numbers_in_room
            end = begin + ExamRoom.numbers_in_room
            df_room_student_science = df_science.iloc[begin:end]
            df_room_students_science.append((idx, room_number, df_room_student_science))
        for idx, room_number, df_room_student_science in df_room_students_science:
            for i in df_room_student_science.index:
                df_room_student_science = df_room_student_science.copy()
                df_room_student_science['考室号'].at[i] = room_number
                df_room_student_science['座位号'].at[
                    i] = i + 1 if i < ExamRoom.numbers_in_room else i - idx * ExamRoom.numbers_in_room + 1
            df_room_student_science.to_excel(writer, sheet_name=room_number, index=False)
            science = science.append(df_room_student_science)
        df_arts_general = arts.sort_values(by=['班级', '考室号'], ascending=[True, True])
        df_science_general = science.sort_values(by=['班级', '考室号'], ascending=[True, True])
        df_arts_general.to_excel(writer, sheet_name='文科', index=False)
        df_science_general.to_excel(writer, sheet_name='理科', index=False)
        # 计算考生座签
        # df_seat_arts = df_arts
        # df_seat_science = df_science
        for i in arts.index:
            arts.loc[i + 0.5] = ['班级', '姓名', '考号', '考室号', '座位号']
            # df2.to_excel(f'{df2.iloc[0,0]}.xlsx',index=False)
        arts.sort_index(inplace=True, ignore_index=True)
        for i in df_science.index:
            science.loc[i + 0.5] = ['班级', '姓名', '考号', '考室号', '座位号']
        science.sort_index(inplace=True, ignore_index=True)
        arts.to_excel(writer, sheet_name='文科座签', index=False)
        science.to_excel(writer, sheet_name='理科座签', index=False)

        writer.close()
        print('successfully done')

    def exam_room(self):
        """
        计算生成各考室学生名单（不分文理科或初中）
        :return:
        """
        df = pd.read_excel(self.path, sheet_name='总表', dtype={'考号': str})
        df.sort_values(by='总分', ascending=False, inplace=True)
        if len(df) % ExamRoom.numbers_in_room != 0:
            room_numbers = [f'第{str(i + 1)}考室' for i in list(range(len(df) // ExamRoom.numbers_in_room + 1))]
        else:
            room_numbers = [f'第{str(i + 1)}考室' for i in list(range(len(df) // ExamRoom.numbers_in_room))]
        df['考室号'] = None
        df['座位号'] = None
        df = df.loc[:, ['班级', '姓名', '考号', '考室号', '座位号']]
        df.reset_index(drop=True, inplace=True)
        print(room_numbers)
        df_room_students = []
        df_temp = pd.DataFrame(columns=df.columns)
        for idx, room_number in enumerate(room_numbers):
            begin = idx * ExamRoom.numbers_in_room
            end = begin + ExamRoom.numbers_in_room
            df_room_student = df.iloc[begin:end]
            df_room_students.append((idx, room_number, df_room_student))

        writer = pd.ExcelWriter(r'D:\成绩统计结果\高一(初中)考室安排表.xlsx')

        for idx, room_number, df_room_student in df_room_students:
            for i in df_room_student.index:
                df_room_student = df_room_student.copy()
                df_room_student['考室号'].at[i] = room_number
                df_room_student['座位号'].at[
                    i] = i + 1 if i < ExamRoom.numbers_in_room else i - idx * ExamRoom.numbers_in_room + 1
            df_room_student.to_excel(writer, sheet_name=room_number, index=False)
            df_temp = df_temp.append(df_room_student)
        df_temp.to_excel(writer, sheet_name='考室安排表', index=False)

        for i in df_temp.index:
            df_temp.loc[i + 0.5] = ['班级', '姓名', '考号', '考室号', '座位号']
        seat_label = df_temp.sort_index()
        seat_label.to_excel(writer, sheet_name='考生座签', index=False)
        writer.close()

    def exam_room_choice(self):
        try:
            self.exam_room_info()
        except:
            self.exam_room()

    @staticmethod
    def make_directory(f):
        def wrapper(*args, **kwargs):
            if not os.path.exists('D:\\成绩统计结果'):
                os.makedirs('D:\\成绩统计结果')
            result = f(*args, **kwargs)
            return result

        return wrapper

    @staticmethod
    def use_time(f):
        def wrapper(*args, **kwargs):
            t1 = time.time()
            results = f(*args, **kwargs)
            t2 = time.time()
            print(f'{f.__name__}用时{(t2 - t1):.1f}秒')
            return results

        return wrapper

    @staticmethod
    def title_lines(f):
        def wrapper(*args, **kwargs):
            print(f'+++++++++++++++高中考试成绩分析处理+++++++++++++++')
            f(*args, **kwargs)
            print(f'--------------成绩分析处理完毕，程序已关闭-----------------')

        return wrapper


if __name__ == '__main__':
    file_path = r'D:\年级管理数据\高2021级\高一上\高一上期末考试\高2021级高一（上）期末考试总成绩表.xlsx'
    # file_path = r'D:\work documents\高2020级\高二上期半期考试.xlsx'
    # ExamRoom.numbers_in_room = 35
    exam_room = ExamRoom(file_path)


    @exam_room.make_directory
    @exam_room.title_lines
    @exam_room.use_time
    def main():
        ExamRoom.numbers_in_room = eval(input('请输入每间考室的人数：'))
        exam_room.exam_room_choice()


    # 运行主程序：
    main()
